自定义view需要注意的几点
- 让view支持wrap_content属性,在onMeasure方法中针对AT_MOST模式做专门处理,否则wrap_content会和match_parent效果一样(继承ViewGroup也同样要在onMeasure中做这个判断处理)
if(widthMeasureSpec == MeasureSpec.AT_MOST && heightMeasureSpec == MeasureSpec.AT_MOST){
setMeasuredDimension(200,200); // wrap_content情况下要设置一个默认值,200只是举个例子,最终的值需要计算得到刚好包裹内容的宽高值
}else if(widthMeasureSpec == MeasureSpec.AT_MOST){
setMeasuredDimension(200,heightMeasureSpec );
}else if(heightMeasureSpec == MeasureSpec.AT_MOST){
setMeasuredDimension(heightMeasureSpec ,200);
}
- 让view支持padding(onDraw的时候,宽高减去padding值,margin由父布局控制,不需要view考虑),自定义ViewGroup需要考虑自身的padding和子view的margin造成的影响
- 在view中尽量不要使用handler,使用view本身的post方法
- 在onDetachedFromWindow中及时停止线程或动画
- 减少在onDraw里面大量计算和对象创建和大量内存分配。
- 应该尽量少用invalidate()次数,尽量调用含有4个参数的invalidate()方法而不是没有参数的invalidate()。没有参数的invalidate会强制重绘整个view。
- view里面耗时的操作layout。减少requestLayout()避免让UI系统重新遍历整棵树。
- 如果你有一个很复杂的布局,不如将这个复杂的布局直接使用你自己的写的ViewGroup来实现。减少了一个树的层次关系全部都是自己测量和layout,达到优化
自定义view的基本流程
自定义View的属性 编写attr.xml文件
在layout布局文件中引用,同时引用命名空间
在View的构造方法中获得我们自定义的属性 ,在自定义控件中进行读取(构造方法拿到attr.xml文件值)
重写onMesure
重写onDraw